/**
 * axios 基于 promise 的 xhr 封装所以 axios 接收 xhr 的参数
 * 并且 axios.interceptors.request.use 拦截器可在请求或者返回被 then 或者 catch 处理之前对它们进行拦截
 */
import axios from "axios";
import APIS from "@/axios/apis";
// 获取参数类型
const toType = obj => ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();

// 配置默认
axios.defaults = Object.assign(axios.defaults, {
	timeout: 10000, //超时
	withCredentials: true,// 跨域请求是否提供凭据信息
});

// http请求拦截器
axios.interceptors.request.use(config => {
	return config;
}, error => {
	return Promise.reject(error);
})

axios.interceptors.response.use(response => {
	return response;
}, error => {
	if (error.response) {
		const stauts = error.response.status;
		if (stauts === 401) {
			window.location.href = `/login?backUrl=${window.location.href}`;
		}
		// 如果根据状态吗判断请求状态在这里做处理
	}
})

// 参数过滤函数
function filterNull(o) {
	for (var key in o) {
		if (o[key] === null) {
			delete o[key];
		}
		if (toType(o[key]) === "string") {
			o[key] = o[key].trim();
		} else if (toType(o[key]) === "object") {
			o[key] = filterNull(o[key]);
		} else if (toType(o[key]) === "array") {
			o[key] = filterNull(o[key]);
		}
	}
	return o;
}

// 错误信息批量处理
function errorFormat(error, reject, callback) {
	// 登录判断不同项目不一样
	if (error && error.status && error.status >= 400) {
		const redirectUrl = encodeURIComponent(window.location.pathname + window.location.search);
		window.location.href = `/login?ROUT=${redirectUrl}`;
	} else {
		reject(error);
	}
	callback && callback(error);
}

// 请求处理批量处理
function requestformat(method, url, params, config, callback) {
	return new Promise((resolve, reject) => {
		let urls = APIS[url].url;
		let allParams = {
			url: urls,
			method,
			config,
		};
		let headers = {};
		if (!urls) {
			return;
		};
		// params空参数或者null, undefined 过滤
		params = params ? filterNull(params) : {}
		// 初始化 config
		if (config && config['headers']) {
			headers = config['headers'];
			delete config['headers'];
			allParams.headers = headers;
		};
		// 如果是 delete 请求，并且需要将参数拼接到 URL 中
		if (method === 'delete' && params) {
			// 将参数拼接到 URL 中
			Object.keys(params).forEach(key => {
				urls = urls.replace(`:${key}`, params[key]);
			});
			allParams.url = urls;
		} else if ('get,delete'.indexOf(method) !== -1) {
			// get 和 delete 请求，参数作为 query 参数
			allParams.params = params;
		} else {
			// post 和 put 请求，参数放在 data 中
			allParams.data = params;
		};
		axios(allParams).then(function (response) {
			if (response && response.status !== 200) {
				return errorFormat(response, reject, callback);
			};
			resolve(response);
			callback && callback(response);
		}).catch(function (error) {
			errorFormat(error, reject, callback);
		});
	});
}


export default {
	request: (url, params, config, callback) => {
		let method = APIS[url].method;
		return requestformat(method, url, params, config, callback);
	},
	get: (url, params, config, callback) => {
		return requestformat('get', url, params, config, callback);
	},
	post: (url, params, config, callback) => {
		return requestformat('post', url, params, config, callback);
	},
	put: (url, params, config = {}, callback) => {
		return requestformat('put', url, params, config, callback);
	},
	delete: (url, params, config, callback) => {
		return requestformat('delete', url, params, config, callback);
	}
};